package org.sippr.rvt2ifc.controller;

import jakarta.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.ClientAbortException;
import org.sippr.rvt2ifc.pojo.*;
import org.sippr.rvt2ifc.utils.PinYin;
import org.sippr.rvt2ifc.utils.SnowflakeIdGenerator;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.sippr.rvt2ifc.service.UploadedFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("/file")
public class FileUploadController {

    @Value("${file.upload.path}")
    private String baseDirectory;
    @Value("${file.upload.json-file-name}")
    private String jsonName;

    @Autowired
    UploadedFileService uploadedFileService;
    // 用于存储客户端请求
    private final ConcurrentHashMap<String, DeferredResult<Result>> clients = new ConcurrentHashMap<>();

    // 超时时间 (300秒)
    private static final long TIMEOUT = 300_000L;

    @PostMapping("/upload")
    public Result upload(MultipartFile file) throws IOException {
        if (file == null)
            return Result.error("文件为空！");
        String oFile = file.getOriginalFilename();
        if (oFile == null)
            return Result.error("文件为空！");

        String storedName = SnowflakeIdGenerator.nextId() + oFile.substring(oFile.lastIndexOf("."));
        Path dir = Paths.get(baseDirectory, "rvt");
        if (!Files.exists(dir)) {
            Files.createDirectories(dir);
        }

        Path filePath = dir.resolve(storedName);
        file.transferTo(new File(filePath.toString()));
        UploadedFile uploadedFile = new UploadedFile();
        uploadedFile.setFileSize(file.getSize());
        uploadedFile.setFileName(oFile);
        uploadedFile.setPinyinName(PinYin.convertToPinyin(oFile));
        uploadedFile.setStoredName(storedName);
        Project project = uploadedFileService.insert(uploadedFile);
        if (project == null) {
            return Result.error("失败");
        }
        // 保存文件信息到 JSON
//        String jsonPath = Paths.get(baseDirectory, jsonName).toString();
//        List<RvtFileInfo> rvtFileInfos = new ArrayList<>();
//        if (new File(jsonPath).exists()) {
//            String json = new String(Files.readAllBytes(Paths.get(jsonPath)));
//            ObjectMapper objectMapper = new ObjectMapper();
//            rvtFileInfos = objectMapper.readValue(json, List.class);
//        }
//        RvtFileInfo rvtFileInfo = new RvtFileInfo();
//        rvtFileInfo.setFileName(filename);
//        rvtFileInfo.setFilePath(filePath.toString());
//        // 添加新文件信息
//        rvtFileInfos.add(rvtFileInfo);
//
//        // 更新 JSON 文件
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.writeValue(new File(jsonPath), rvtFileInfos);
        List<UploadedFile> waitFileList = uploadedFileService.getWaitFile();

        // 如果有新数据，通知所有客户端
        if (!waitFileList.isEmpty()) {
            for (DeferredResult<Result> deferredResult : clients.values()) {
                deferredResult.setResult(Result.success(waitFileList));
            }
        }
        return Result.success(project);
    }

    @GetMapping("/download/{fileName}")
    public void downloadFile(@PathVariable String fileName, HttpServletResponse response) {
        Path filePath = Paths.get(baseDirectory, "rvt", fileName).normalize();
        File file = new File(filePath.toString());
        if (!file.exists()) {
            response.setStatus(HttpStatus.NOT_FOUND.value());
            return;
        }

        try (InputStream inputStream = new FileInputStream(file);
             OutputStream outputStream = response.getOutputStream()) {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
            response.setContentLengthLong(file.length());

            byte[] buffer = new byte[1024 * 1024]; // 1MB buffer
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
                outputStream.flush();
            }
        } catch (ClientAbortException e) {
            // 客户端中断连接，无需处理
            System.out.println("Client aborted download: " + fileName);
        } catch (IOException e) {
            System.out.println(e);
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
    }

//    @GetMapping("/download/{fileName}")
//    public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
//        try {
//            // 构建文件路径
//            Path filePath = Paths.get(baseDirectory, "rvt", fileName).normalize();
//            Resource resource = (Resource) new UrlResource(filePath.toUri());
//
//            // 检查文件是否存在和可读
//            if (!resource.exists() || !resource.isReadable()) {
//                return ResponseEntity.notFound().build();
//            }
//
//            // 设置响应头，告知浏览器以下载方式处理文件
//            return ResponseEntity.ok()
//                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
//                    .body(resource);
//
//        } catch (MalformedURLException e) {
//            return ResponseEntity.internalServerError().build();
//        }
//    }

    @GetMapping("/getWaitList")
    public DeferredResult<Result> getWaitList() {
        // 创建 DeferredResult，超时时间为30秒
        DeferredResult<Result> deferredResult = new DeferredResult<>(TIMEOUT, Result.success("No updates"));

        // 处理完成或超时逻辑
        deferredResult.onTimeout(() -> clients.remove(deferredResult.toString()));
        deferredResult.onCompletion(() -> clients.remove(deferredResult.toString()));

        // 将请求存储到集合中
        clients.put(deferredResult.toString(), deferredResult);

        // 检查是否有新的数据
        List<UploadedFile> waitFileList = uploadedFileService.getWaitFile();
        if (!waitFileList.isEmpty()) {
            deferredResult.setResult(Result.success(waitFileList)); // 立即返回数据
        }

        return deferredResult;
    }

}
